import { Tools } from './../../../../tools/tools';
import { Component, OnInit, OnDestroy, AfterViewInit } from '@angular/core';
import { NzMessageService } from 'ng-zorro-antd';
import { BaseService, DataRegisterService, PageService } from 'src/app/services';
import { EventManagerService } from 'src/app/services/event-manager.service';
import { OrganizationService } from 'src/app/services/organization.service';
import { UploadService } from 'src/app/services/upload.service';
import { PermitConfig, PermitConfigId } from '../../../models';
import { EngineService } from '../../../services/engine.service';
import { BaseFieldComponent } from '../base-field/base-field.component';

@Component({
  selector: 'zepride-column-table',
  templateUrl: './column-table.component.html',
  styleUrls: ['./column-table.component.less', '../field.common.less']
})
export class ColumnTableComponent extends BaseFieldComponent implements OnInit, AfterViewInit, OnDestroy {

  rows: any[] = [];

  permitConfig: PermitConfig[] = [
    { mode: 'query', permitId: '查看', permitName: '', authObjectId: '' },
    { mode: 'edit', permitId: '编辑', permitName: '', authObjectId: '' }
  ];

  editable = true;

  get bindData() {
    const bindField = this.componentData.bindField;
    if (bindField) {
      const list = this.formateData();
      this.dataModel[bindField] = list;
      return this.dataModel[bindField];
    } else {
      return this.componentData.defaultValue;
    }
  }

  get bindDataFromModel() {
    const bindField = this.componentData.bindField;
    if (bindField) {
      return this.dataModel[bindField];
    } else {
      return this.componentData.defaultValue;
    }
  }

  getCellSpan(last: boolean, rowLength: number, name: string, item) {
    let span = 0;
    if (!item) {
      return 8;
    }

    const width = item.component.extends.width;
    if (width == 'half') {
      span = 8;
    } else if (width == 'full') {
      span = 20;
    }

    if (!name) {
      if (span == 20) {
        span = 24;
      }
      if (span == 8) {
        span = 12;
      }
    }
    return span;
  }

  constructor(
    protected engineService: EngineService,
    protected baseSvr: BaseService,
    protected eventSvr: EventManagerService,
    protected orgSvr: OrganizationService,
    public uploadService: UploadService,
    protected msg: NzMessageService,
    protected pageSvr: PageService,
    protected dataRegisterService: DataRegisterService
  ) {
    super(engineService, baseSvr, eventSvr, orgSvr, uploadService, msg, dataRegisterService);
  }

  ngOnDestroy(): void {
    if (this.modelChange$) {
      this.modelChange$.unsubscribe();
    }
  }

  ngOnInit(): void {
    this.componentData.extends.fields || (this.componentData.extends.fields = []);

    if (this.bindDataFromModel) {
      for (let i = 0; i < this.bindDataFromModel.length; i++) {
        const item = this.bindDataFromModel[i];
        for (let key in item) {
          const keyFinal = `${this.componentData.bindField}[${i}].${key}`;
          this.dataModel[keyFinal] = item[key];
        }
      }
    }

    if (this.componentData.extends.loop) {
      const refBindField = this.componentData.extends.loop.component.bindField;

      if (this.dataModel[refBindField]) {
        // tslint:disable-next-line: radix
        const loopCount = parseInt(this.dataModel[refBindField]);
        this.loopRender(loopCount);
      }
    }
    else {
      let list = this.formateData();
      if (list.length == 0) {
        list = this.bindDataFromModel;
      }
      if (list.length > 0) {
        for (const item of list) {
          this.addRow(item);
        }
      } else {
        this.addRow();
      }
    }
    this.eventSvr.callEvents('AutoForm.filterComs', this.componentData.extends.fields);
    this.registerModelChange();
  }

  ngAfterViewInit() {
    setTimeout(() => {
      const authData = this.setAuthorityData();
      this.zeprideAuthorityData = {
        ...authData,
        afterChecked: this.afterAuthChecked.bind(this)
      };
    });
  }

  registerModelChange() {
    this.modelChange$ = this.engineService.dataModelChange$.subscribe(data => {
      if (
        data.identifyId !== this.componentData.identifyId &&
        this.componentData.extends.loop &&
        data.tmpComItemId == this.componentData.extends.loop.tplComponentTempId &&
        !isNaN(data.value)
      ) {
        // tslint:disable-next-line: radix
        const loopCount = parseInt(data.value);
        this.loopRender(loopCount);
      }
    });
  }

  loopRender(loopCount: number) {
    if (this.rows.length != loopCount) {
      if (this.rows.length > loopCount) {
        // dataModel 中移除多余的数据
        for (let i = loopCount; i < this.rows.length; i++) {
          let keys = Object.keys(this.dataModel);
          for (let key of keys) {
            if (key.indexOf(`${this.componentData.bindField}[${i}]`) > -1) {
              delete this.dataModel[key];
            }
          }
        }
      }

      this.rows = [];
      setTimeout(() => {
        for (let i = 0; i < loopCount; i++) {
          this.addRow();
        }
      }, 1000)

    }
  }

  private formateData() {
    // demo: xxx[0].bbb
    const list = [];
    for (let i = 0; i < this.rows.length; i++) {
      const obj = {};
      const row = this.rows[i];
      for (let rowItem of row) {
        const component = rowItem.component;
        if (!component.bindField) continue;

        const bindField: string = component.bindField;
        obj[rowItem.sourceBindField] = this.dataModel[bindField];
      }
      list.push(obj);
    }
    return list;
  }

  addRow(defaultValues?: any[]) {
    const row = [];
    for (let i = 0; i < this.componentData.extends.fields.length; i++) {
      let fieldItem = this.componentData.extends.fields[i];
      fieldItem = JSON.parse(JSON.stringify(fieldItem));
      if (fieldItem.component) {
        const bindField = fieldItem.component.bindField;
        fieldItem.sourceBindField = bindField;
        // demo: xxx[0].bbb
        const fieldKey = `${this.componentData.bindField}[${this.rows.length}].${bindField}`;
        fieldItem.component.bindField = fieldKey;

        if (fieldItem.component.selector == "space-occupying") {
          if (fieldItem.component.extends.spaceChars.find(x => x.bindField == "序号")) {
            this.dataModel[`${this.componentData.bindField}[${this.rows.length}].序号`] = this.rows.length + 1;
          }
          if (fieldItem.component.extends.spaceChars.find(x => x.bindField == "序号(大写)")) {
            this.dataModel[`${this.componentData.bindField}[${this.rows.length}].序号(大写)`] = this.numberToBig(this.rows.length + 1);
          }
        }

        fieldItem.component.extends || (fieldItem.component.extends = {});
        fieldItem.component.extends.indexNo = this.rows.length;
        if (defaultValues) {
          fieldItem.component.defaultValue = defaultValues[bindField];
        }
      }
      row.push(fieldItem);
    }
    this.rows.push(row);
  }

  pageSavedHandle = async () => {
    const data = this.formateData();
    if (!this.componentData.bindField || !data.length) {
      return;
    }

    // 解析供应商系统对接的数据
    let packages = [];
    for (let i = 0; i < this.rows.length; i++) {
      const row = this.rows[i];
      let packageItem: any = {};

      for (let rowItem of row) {
        const component = rowItem.component;
        if (!component.extends.mapField || component.extends.mapField.length == 0) { continue; }
        const key = component.extends.mapField[1];
        const bindField = component.bindField;
        packageItem[key] = this.dataModel[bindField];
      }
      packageItem.PackageNum = i;
      packageItem.YouJianPackageId = Tools.GetGuid();

      packages.push(packageItem);

      data[i].YouJianPackageId = packageItem.YouJianPackageId;
    }

    this.mapDataModel.Packages = packages;
    this.dataModel[this.componentData.bindField] = data;
    this.generateOutputHtml();
  }

  generateOutputHtml() {
    if (!this.componentData.bindField) return;
    let tableHeader: string[] = [];
    for (let item of this.componentData.extends.fields) {
      if (item.isOutput == false) continue;
      tableHeader.push(`<th nzAlign="center">${item.name}</th>`);
    }
    const tableBody: string[] = [];
    // tslint:disable-next-line: prefer-for-of
    for (let i = 0; i < this.rows.length; i++) {
      const row = [];
      const rowItem: any[] = this.rows[i];

      for (let j = 0; j < rowItem.length; j++) {
        const rowDataItem = rowItem[j];
        if (rowDataItem.isOutput == false) { continue; }
        const cData = this.dataModel[this.componentData.bindField];
        const sData = cData[i];

        let data;
        if (sData) {
          data = sData[rowDataItem.sourceBindField];
          if (Array.isArray(data)) {
            data = '数组对象';
          }
        }

        row.push(`<td>${data}</td>`);
      }

      tableBody.push('<tr>' + row.join('') + '</tr>');
    }

    const dataTableHtml = `<table>
      <thead>
        <tr>${tableHeader.join('')}</tr>
      </thead>
      <tbody>
        ${tableBody.join('')}
      </tbody>
    </table>`;

    this.dataModel[this.componentData.bindField + "html"] = dataTableHtml;
  }

  numberToBig(num: any) {
    const changeNum = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九']; // changeNum[0] = "零"
    const unit = ['', '十', '百', '千', '万'];
    // tslint:disable-next-line: radix
    num = parseInt(num);
    const getWan = (temp: any) => {
      const strArr = temp.toString().split('').reverse();
      let newNum = '';
      for (let i = 0; i < strArr.length; i++) {
        newNum = (i == 0 && strArr[i] == 0 ? '' : (i > 0 && strArr[i] == 0 && strArr[i - 1] == 0 ? '' : changeNum[strArr[i]] + (strArr[i] == 0 ? unit[0] : unit[i]))) + newNum;
      }
      return newNum;
    };
    const overWan = Math.floor(num / 10000);
    let noWan: any = num % 10000;
    if (noWan.toString().length < 4) { noWan = '0' + noWan; }
    return overWan ? getWan(overWan) + '万' + getWan(noWan) : getWan(num);
  }

  getChangeLogSource() {
    const list: string[] = (this.dataChangeLog.sourceValue as Array<any>).map((x, index) => {
      const result = [];
      // tslint:disable-next-line: forin
      for (const key in x) {
        result.push(`${key}:${x[key]}`);
      }
      return '第' + (index + 1) + '行：' + result.join(' | ');
    });
    return list.join('\n');
  }

  getChangeLogTarget() {
    const list: string[] = (this.dataChangeLog.targetValue as Array<any>).map((x, index) => {
      const result = [];
      // tslint:disable-next-line: forin
      for (const key in x) {
        result.push(`${key}:${x[key]}`);
      }

      return '第' + (index + 1) + '行：' + result.join(' | ');
    });

    return list.join('\n');
  }

  afterAuthChecked(params: {
    permitId: PermitConfigId;
    isAuthorized: boolean;
  }) {
    if (!params.isAuthorized && params.permitId === '编辑') {
      this.editable = false;
    }
  }

  getObjectKeys(obj: any[]): string[] {
    if (!obj) {
      return [];
    }
    const item = obj[0];
    return Object.keys(item);
  }
}
